package ratkit.repast;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;

import ratkit.util.RatKitConstants;
import repast.simphony.context.Context;
import repast.simphony.dataLoader.ContextBuilder;
import repast.simphony.engine.environment.RunEnvironment;
import repast.simphony.parameter.Parameters;

/**
 * @author Önder Gürcan, İbrahim Çakırlar
 * @version 1.0
 */
@SuppressWarnings("rawtypes")
abstract public class RepastScenarioBuilder implements ContextBuilder<Object> {

	/**
	 * Sub context for the test environment.
	 */
	private RepastTestEnvironment testEnvironment;
	/**
	 * Created context instance..
	 */
	private Context<Object> context;

	/*
	 * @see
	 * repast.simphony.dataLoader.ContextBuilder#build(repast.simphony.context
	 * .Context)
	 */
	@Override
	public Context<Object> build(Context<Object> context) {
		// set context..
		this.setContext(context);

		// initialize grid and space..
		createGridAndContinuousSpace();
		// creates the simulation context.
		context.addSubContext(getTestEnvironment());
		// create test agent instance and and add to the test context.
		createTestAgent();
		// create agents under test..
		createAgents();
		return context;
	}

	/**
	 * Creates the simulation grid and continuous space..
	 */
	abstract protected void createGridAndContinuousSpace();

	/**
	 * Creates the simulation essential agents for the test environment.
	 */
	abstract protected void createAgents();

	/**
	 * Creates the tester agent instance and adds tester agent to the test
	 * context.
	 */
	private void createTestAgent() {
		// get working directory value.
		// working directory value is the directory of the required simulation
		// files like user_path.xml,test_agent.xml..etc
		Parameters p = RunEnvironment.getInstance().getParameters();
		String workingDir = (String) p
				.getValue(RatKitConstants.WORKING_DIRECTORY);
		try {
			// read test_agent file..
			BufferedReader reader = new BufferedReader(new FileReader(new File(
					workingDir, RatKitConstants.TEST_AGENT_FILE)));
			// read first line...
			String testAgentClassName = reader.readLine();
			// remove XML tags..
			testAgentClassName = testAgentClassName.replaceAll("<string>", "");
			testAgentClassName = testAgentClassName.replaceAll("</string>", "");
			// create tester agent instance
			getTestEnvironment().createTestAgent(testAgentClassName);
			// close file reader...
			reader.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Returns the test environment instance. Test environment instance is the
	 * sub context for the tester agent.
	 * 
	 * @return test environment context
	 */
	private RepastTestEnvironment getTestEnvironment() {
		if (this.testEnvironment == null) {
			this.testEnvironment = new RepastTestEnvironment(
					RatKitConstants.TEST_ENVIRONMENT);
		}
		return this.testEnvironment;
	}

	/**
	 * Sets the context of the scenario builder.
	 * 
	 * @param context
	 *            context to set.
	 */
	public void setContext(Context<Object> context) {
		this.context = context;
	}

	/**
	 * Returns the context of the builder.
	 */
	public Context getContext() {
		return context;
	}
}
